import {
  REG_ARR,
  REG_OBJ,
  REG_SPACE
} from './regular';

import {
  transformToKebab
} from './utils';

/**
 * Map {
 *   el: {
 *     type: class/style,
 *     expression: 表达式
 *   }
 * }
 */

/**
 * 编译属性
 * @param {object} vm 实例对象
 * @param {*} el 枚举的每一个元素节点
 * @param {*} name 标签属性名
 * @param {*} value 标签属性值
 */
export function compileAttr(vm, el, name, value) {
  //替换所有空格字符为空
  value = value.replace(REG_SPACE, '');
  //name -> :class 去掉冒号
  name = name.replace(':', '');


  // console.log(el); div h1 h2 p
  vm.$stylePool.set(el, {
    type: name,
    expression: value
  });

  switch (name) {
    case 'class':
      //class属性值为对象的情况：
      if (REG_OBJ.test(value)) {
        // console.log('obj:' + value);
        //obj:{danger:hasError}

        const keyValueArr = value.match(REG_OBJ)[1].split(',');
        // console.log(value.match(REG_OBJ));
        //["{danger:hasError}", "danger:hasError", index: 0, input: "{danger:hasError}", groups: undefined]

        // console.log(keyValueArr);
        //["danger:hasError"]

        let classStr = '';

        keyValueArr.forEach(item => {
          const [key, value] = item.split(':');
          // console.log(key, value); danger hasError

          //vm[value.trim()] -> vm.hasError
          //如vm.hasError存在返回true
          if (vm[value.trim()]) {
            classStr += ` ${key.trim()}`;
          }
          // console.log(classStr); danger big
        });

        //设置标签里class属性
        el.setAttribute('class', classStr.trim());
        // console.log(el);
        //<p class="danger big"> This is Content </p >

      } else if (REG_ARR.test(value)) {
        //class属性值为数组的情况：

        // console.log('arr:' + value);
        //arr:['box',isShow?'show':'',hasError?'danger':'']

        const classArr = renderArr(vm, value);
        // console.log(classArr);
        //["box", "show", "danger"]

        el.setAttribute('class', classArr.join(' ').trim());
        // console.log(el);
        //<div class="box show danger">...</div>

      }
      break;
    case 'style':
      let styleStr = '';
      if (REG_OBJ.test(value)) {
        // console.log(value);
        //'{display:titleShow?'block':'none',color:subTitleColor}'

        const styleObj = renderObj(vm, value);
        // console.log(styleObj);
        //{display: "block", color: "orange"}

        //枚举styleObj
        for (let key in styleObj) {
          // console.log(key); display/color/fontSize
          //将fontSize驼峰写法转为 font-size
          styleStr += `${transformToKebab(key)}:${styleObj[key]};`;
          // console.log(styleStr);
          //display:block;color:orange;font-size:20px;
        }

      } else if (REG_ARR.test(value)) {
        // console.log(value);
        //[titleStyle,{display:titleShow?'block':'none'}]

        const styleArr = renderArr(vm, value);
        // console.log(styleArr);
        /**
         * [
         *   {color: "#fff", fontSize: "20px"},
         *   {display: "block"}
         * ]
         */

        styleArr.forEach(item => {
          // console.log(item);
          //{color: "#fff", fontSize: "20px"}

          // 枚举item
          for (let key in item) {
            // console.log(key); color/fontSize/display
            styleStr += `${transformToKebab(key)}:${item[key]};`;
          }
          // console.log(styleStr);
          //color:#fff;font-size:20px;display:block;
        })
      }
      el.setAttribute('style', styleStr);
      // console.log(el);
      //<h2 style="display:block;color:orange;font-size:20px;">This is Sub_Title</h2>

      // console.log(el);
      //<h1 style="color:#fff;font-size:20px;display:block;">This is Title</h1>

      break;
    default:
      break;
  }
}

/**
 * 将字符串数组处理成一个数组
 * @param {object} vm 实例对象
 * @param {*} value 标签属性值
 */
function renderArr(vm, value) {
  //new Function(this, 参数1)返回一个新的函数实例, 确保是真的数组
  //with(作用域名称){} 可以改变作用域 
  //这个作用域专门管理vm底下的方法如isShow
  //立即执行函数传入vm实例
  //value -> '['box',isShow?'show':'',hasError?'danger':'']'

  // console.log(new Function('vm', `with(vm){
  //   return ${value};
  // }`));

  const _arr = (new Function(
    'vm',
    `with(vm){
      return ${value};
    }`
  ))(vm);
  //过滤掉如果为false时显示 空字符串的问题
  return _arr.filter(item => item);
}

/**
 * 让value里的逻辑方法执行，如titleShow?'block':'none'
 * 将字符串数组处理成一个数组
 * @param {object} vm 实例对象
 * @param {*} value 标签属性值
 */
function renderObj(vm, value) {
  return (new Function(
    'vm',
    `with(vm){
      return ${value};
    }`
  ))(vm);
}